import React, { useState, useEffect } from 'react';
import { useQueryClient } from 'react-query';
import { 
  Box, 
  Paper, 
  Typography, 
  Button, 
  CircularProgress, 
  Divider, 
  Accordion, 
  AccordionSummary, 
  AccordionDetails,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  Chip
} from '@mui/material';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { JWT_TOKEN, SUPER_JWT_TOKEN } from 'config';
import Storage from 'libs/storage';
import Axios from 'libs/axios';

// Import query functions
import * as AllQueries from 'api/queries';

/**
 * QueryTester - A component to test React Query behavior and authentication
 *
 * This component allows you to:
 * - Test any query from api/queries.js
 * - Check token status
 * - Clear React Query cache
 * - Delete authentication tokens
 * - See actual network requests with headers
 * - Compare cached vs. fresh responses
 */
const QueryTester = ({ initialQuery = 'Me', isVisible = true }) => {
  const queryClient = useQueryClient();
  const [selectedQuery, setSelectedQuery] = useState(initialQuery);
  const [queryParams, setQueryParams] = useState({});
  const [freshResult, setFreshResult] = useState(null);
  const [cachedResult, setCachedResult] = useState(null);
  const [error, setError] = useState(null);
  const [authHeader, setAuthHeader] = useState('No request made yet');
  const [loading, setLoading] = useState(false);
  const [cachingStatus, setCachingStatus] = useState({
    cacheExists: false,
    staleTime: 'unknown',
    dataUpdatedAt: null
  });

  // Get token info
  const [tokenState, setTokenState] = useState({
    jwtToken: null,
    superToken: null,
    jwtDecoded: null,
    superDecoded: null
  });

  // Available queries from the queries.js file
  const availableQueries = Object.keys(AllQueries);

  // Function to refresh token status
  const refreshTokenInfo = () => {
    const jwtToken = Storage.getItem(JWT_TOKEN);
    const superToken = Storage.getItem(SUPER_JWT_TOKEN);
    
    let jwtDecoded = null;
    let superDecoded = null;

    try {
      // We can't actually decode the tokens here since we'd need a library like jwt-decode
      // but we can show if they're present and their length
      jwtDecoded = jwtToken ? { 
        length: jwtToken.length,
        preview: jwtToken.substring(0, 15) + '...' 
      } : null;
      
      superDecoded = superToken ? { 
        length: superToken.length,
        preview: superToken.substring(0, 15) + '...' 
      } : null;
    } catch (e) {
      console.error('Error examining tokens:', e);
    }

    setTokenState({
      jwtToken: jwtToken ? 'Present' : 'Missing',
      superToken: superToken ? 'Present' : 'Missing',
      jwtDecoded,
      superDecoded
    });
  };

  // Check query cache info
  const checkCacheStatus = () => {
    if (!selectedQuery) return;
    
    const cacheKey = [selectedQuery]; // Simplified - actual key might be more complex
    const queryCache = queryClient.getQueryCache();
    const cachedQuery = queryCache.find(cacheKey);
    
    if (cachedQuery) {
      setCachingStatus({
        cacheExists: true,
        staleTime: cachedQuery.options?.staleTime || 0,
        dataUpdatedAt: cachedQuery.state.dataUpdatedAt
      });
    } else {
      setCachingStatus({
        cacheExists: false,
        staleTime: 'unknown',
        dataUpdatedAt: null
      });
    }
  };

  // Load initial state
  useEffect(() => {
    refreshTokenInfo();
    checkCacheStatus();
  }, [selectedQuery]);

  // Test fresh query with network request
  const testFreshQuery = async () => {
    setLoading(true);
    setError(null);
    setFreshResult(null);
    setAuthHeader('Pending...');
    
    try {
      // Get the query function
      const queryFn = AllQueries[selectedQuery];
      if (!queryFn) {
        throw new Error(`Unknown query: ${selectedQuery}`);
      }
      
      // Check current axios auth header
      let headerValue = 'Not available';
      try {
        const instance = Axios.authenticated();
        headerValue = instance.defaults.headers.common.Authorization || 'No Authorization header';
      } catch (e) {
        headerValue = `Error getting header: ${e.message}`;
      }
      setAuthHeader(headerValue);
      
      // Execute the query with a forced network request
      const networkResult = await queryFn();
      setFreshResult(networkResult);
      
      // Also check what's in the cache now
      checkCachedResult();
    } catch (err) {
      setError(err);
    } finally {
      setLoading(false);
    }
  };
  
  // Get the cached result for comparison
  const checkCachedResult = () => {
    const cacheKey = [selectedQuery]; // Simplified - might need to match the actual query key pattern
    const cachedData = queryClient.getQueryData(cacheKey);
    setCachedResult(cachedData);
    checkCacheStatus();
  };

  // Clear React Query cache for this query
  const clearQueryCache = () => {
    queryClient.removeQueries([selectedQuery]);
    setCachedResult(null);
    checkCacheStatus();
  };
  
  // Clear all React Query caches
  const clearAllCaches = () => {
    queryClient.clear();
    setCachedResult(null);
    checkCacheStatus();
  };
  
  // Delete authentication tokens
  const clearTokens = () => {
    Storage.deleteKey(JWT_TOKEN);
    Storage.deleteKey(SUPER_JWT_TOKEN);
    refreshTokenInfo();
  };

  if (!isVisible) return null;

  return (
    <Paper 
      elevation={3} 
      sx={{ 
        p: 3, 
        m: 2, 
        border: '2px solid #e0e0e0',
        borderRadius: 2,
        maxWidth: '900px',
        backgroundColor: '#fafafa'
      }}
    >
      <Typography variant="h5" gutterBottom color="primary">
        React Query Tester
      </Typography>
      
      {/* Query Selection */}
      <Box sx={{ mb: 3 }}>
        <FormControl fullWidth variant="outlined" sx={{ mb: 2 }}>
          <InputLabel>Select Query to Test</InputLabel>
          <Select
            value={selectedQuery}
            onChange={(e) => setSelectedQuery(e.target.value)}
            label="Select Query to Test"
          >
            {availableQueries.map(query => (
              <MenuItem key={query} value={query}>{query}</MenuItem>
            ))}
          </Select>
        </FormControl>
      </Box>
      
      {/* Token Information Section */}
      <Accordion defaultExpanded>
        <AccordionSummary expandIcon={<ExpandMoreIcon />}>
          <Typography variant="subtitle1">Authentication Status</Typography>
        </AccordionSummary>
        <AccordionDetails>
          <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
            <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
              <Typography variant="body2">JWT Token:</Typography>
              <Chip 
                label={tokenState.jwtToken} 
                color={tokenState.jwtToken === 'Present' ? 'success' : 'error'} 
                size="small" 
              />
            </Box>
            
            <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
              <Typography variant="body2">Super JWT Token:</Typography>
              <Chip 
                label={tokenState.superToken} 
                color={tokenState.superToken === 'Present' ? 'success' : 'error'} 
                size="small" 
              />
            </Box>
            
            {tokenState.jwtDecoded && (
              <Typography variant="body2" sx={{ mt: 1, fontFamily: 'monospace' }}>
                JWT Token Length: {tokenState.jwtDecoded.length}, Preview: {tokenState.jwtDecoded.preview}
              </Typography>
            )}
            
            {tokenState.superDecoded && (
              <Typography variant="body2" sx={{ fontFamily: 'monospace' }}>
                Super Token Length: {tokenState.superDecoded.length}, Preview: {tokenState.superDecoded.preview}
              </Typography>
            )}
          </Box>
        </AccordionDetails>
      </Accordion>
      
      {/* Auth Header Section */}
      <Accordion defaultExpanded>
        <AccordionSummary expandIcon={<ExpandMoreIcon />}>
          <Typography variant="subtitle1">Authorization Header</Typography>
        </AccordionSummary>
        <AccordionDetails>
          <Typography variant="body2" sx={{ fontFamily: 'monospace', wordBreak: 'break-all' }}>
            {authHeader}
          </Typography>
        </AccordionDetails>
      </Accordion>

      {/* Cache Status Section */}
      <Accordion defaultExpanded>
        <AccordionSummary expandIcon={<ExpandMoreIcon />}>
          <Typography variant="subtitle1">React Query Cache Status</Typography>
        </AccordionSummary>
        <AccordionDetails>
          <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
            <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
              <Typography variant="body2">Cache Exists:</Typography>
              <Chip 
                label={cachingStatus.cacheExists ? 'Yes' : 'No'} 
                color={cachingStatus.cacheExists ? 'success' : 'error'} 
                size="small" 
              />
            </Box>
            
            {cachingStatus.cacheExists && (
              <>
                <Typography variant="body2">
                  Stale Time: {cachingStatus.staleTime === 0 ? '0 (immediate)' : cachingStatus.staleTime + 'ms'}
                </Typography>
                
                {cachingStatus.dataUpdatedAt && (
                  <Typography variant="body2">
                    Last Updated: {new Date(cachingStatus.dataUpdatedAt).toLocaleString()}
                    {' '}
                    ({Math.round((Date.now() - cachingStatus.dataUpdatedAt) / 1000)}s ago)
                  </Typography>
                )}
              </>
            )}
          </Box>
        </AccordionDetails>
      </Accordion>
      
      {/* Action Buttons */}
      <Box sx={{ my: 3, display: 'flex', flexWrap: 'wrap', gap: 2 }}>
        <Button 
          variant="contained" 
          color="primary" 
          onClick={testFreshQuery}
          disabled={loading}
          startIcon={loading ? <CircularProgress size={20} /> : null}
        >
          Test Query (Fresh)
        </Button>
        
        <Button 
          variant="outlined" 
          color="primary" 
          onClick={checkCachedResult}
        >
          Check Cache
        </Button>
        
        <Button 
          variant="outlined" 
          onClick={clearQueryCache}
        >
          Clear This Query Cache
        </Button>
        
        <Button 
          variant="outlined" 
          onClick={clearAllCaches}
        >
          Clear All Caches
        </Button>
        
        <Button 
          variant="outlined" 
          color="error" 
          onClick={clearTokens}
        >
          Delete Tokens
        </Button>
        
        <Button 
          variant="outlined" 
          onClick={refreshTokenInfo}
        >
          Refresh Status
        </Button>
      </Box>
      
      {/* Error Display */}
      {error && (
        <Box sx={{ mb: 3, p: 2, bgcolor: '#ffebee', borderRadius: 1 }}>
          <Typography variant="subtitle2" color="error">
            Error:
          </Typography>
          <Typography variant="body2">
            {error.message || JSON.stringify(error)}
          </Typography>
          {error.response && (
            <Box sx={{ mt: 1 }}>
              <Typography variant="subtitle2">Response Status: {error.response.status}</Typography>
              <pre style={{ overflow: 'auto', maxHeight: '200px' }}>
                {JSON.stringify(error.response.data, null, 2)}
              </pre>
            </Box>
          )}
        </Box>
      )}
      
      {/* Results Comparison */}
      <Accordion defaultExpanded={!!(freshResult || cachedResult)}>
        <AccordionSummary expandIcon={<ExpandMoreIcon />}>
          <Typography variant="subtitle1">Results Comparison</Typography>
        </AccordionSummary>
        <AccordionDetails>
          <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
            {/* Fresh Network Result */}
            <Box>
              <Typography variant="subtitle2" gutterBottom>
                Fresh Network Result:
              </Typography>
              {freshResult ? (
                <pre style={{ overflow: 'auto', maxHeight: '300px', backgroundColor: '#f5f5f5', padding: '10px' }}>
                  {JSON.stringify(freshResult.data, null, 2)}
                </pre>
              ) : (
                <Typography variant="body2" color="text.secondary">No fresh result</Typography>
              )}
            </Box>
            
            <Divider />
            
            {/* Cached Result */}
            <Box>
              <Typography variant="subtitle2" gutterBottom>
                Cached Result:
              </Typography>
              {cachedResult ? (
                <pre style={{ overflow: 'auto', maxHeight: '300px', backgroundColor: '#f5f5f5', padding: '10px' }}>
                  {JSON.stringify(cachedResult.data, null, 2)}
                </pre>
              ) : (
                <Typography variant="body2" color="text.secondary">No cached result</Typography>
              )}
            </Box>
            
            {/* Result Comparison */}
            {freshResult && cachedResult && (
              <Box>
                <Typography variant="subtitle2" gutterBottom>
                  Results Match: 
                  {JSON.stringify(freshResult.data) === JSON.stringify(cachedResult.data) 
                    ? ' ✓ Yes' 
                    : ' ✗ No'}
                </Typography>
              </Box>
            )}
          </Box>
        </AccordionDetails>
      </Accordion>
    </Paper>
  );
};

// HOC wrapper for easy usage
const withQueryTester = (WrappedComponent, queryToTest = 'Me', isVisible = true) => {
  return function WithQueryTester(props) {
    return (
      <>
        <QueryTester initialQuery={queryToTest} isVisible={isVisible} />
        <WrappedComponent {...props} />
      </>
    );
  };
};

export { QueryTester, withQueryTester };

